package level

import (
	"bytes"
	"encoding/gob"
	"reflect"

	"google.golang.org/protobuf/proto"
)

// Bytes 对象转换字节码.
func Bytes(obj interface{}) []byte {
	value := reflect.ValueOf(obj)
	// nolint
	switch value.Kind() {
	case reflect.Ptr, reflect.Struct:
		if m, ok := value.Interface().(proto.Message); ok {
			bs, err := proto.Marshal(m)
			if err == nil {
				return bs
			}

			panic(err)
		}

		if m, ok := value.Interface().(Byteser); ok {
			return m.Bytes()
		}
	case reflect.Slice:
		e := reflect.TypeOf(obj).Elem()
		if e.Kind() == reflect.Uint8 {
			if bs, ok := obj.([]byte); ok {
				return bs
			}
		}
	}

	buffer := new(bytes.Buffer)
	encoder := gob.NewEncoder(buffer)

	if err := encoder.Encode(obj); err != nil {
		panic(err)
	}

	return buffer.Bytes()
}

// Put 写入数据.
func (p *Service) Put(key []byte, o interface{}) {
	if err := p.DB.Put(key, Bytes(o), nil); err != nil {
		panic(err)
	}
}
